let dragEl = document.querySelector(".drag")
let container = document.querySelector(".box")


class Drag {
  constructor(target, options = { limit: true, drag: true, zoom: true, minWidth: 0, minHeight: 0 }) {
    this.target = target
    this.options = options
    this.init()
  }
  // 初始化
  init() {
    this.target.style.position = "relative"
    this.getBoundary()
    if (this.options.drag) {
      this.drag()
    }
    if (this.options.zoom) {
      this.addHorn()
      this.addBorder()
      this.leftZoom()
      this.rightZoom()
      this.topZoom()
      this.bottomZoom()
      this.leftTopZoom()
      this.leftBottomZoom()
      this.rightTopZoom()
      this.rightBottomZoom()
    }
  }
  // 获取父元素的宽高
  getBoundary() {
    this.maxWidth = this.target.parentNode.clientWidth
    this.maxHeight = this.target.parentNode.clientHeight
  }
  // 获取自身起始信息
  getInfo(e) {
    this.width = this.target.clientWidth
    this.height = this.target.clientHeight
    let translateStr = this.target.style.transform
    if (translateStr) {
      const reg = /\d+/g
      let translateArr = translateStr.match(reg)
      this.tx = Number(translateArr[0])
      this.ty = Number(translateArr[1])
    } else {
      this.tx = 0
      this.ty = 0
    }
    this.startX = e.clientX
    this.startY = e.clientY
  }
  // 拖动实现
  drag() {
    this.target.addEventListener("mousedown", (e) => {
      this.getInfo(e)
      document.onmousemove = (e) => {
        if (this.options.limit) {
          this.distanceX = Math.max(0, Math.min(this.tx + e.clientX - this.startX, this.maxWidth - this.width))
          this.distanceY = Math.max(0, Math.min(this.ty + e.clientY - this.startY, this.maxHeight - this.height))
        } else {
          this.distanceX = this.tx + e.clientX - this.startX
          this.distanceY = this.ty + e.clientY - this.startY
        }
        this.target.style.transform = `translate(${this.distanceX}px, ${this.distanceY}px)`
      }
      document.onmouseup = () => {
        document.onmousemove = null
      }
    })
  }
  // 添加四个角
  addHorn() {
    this.leftTop = document.createElement("div")
    this.rightTop = document.createElement("div")
    this.leftBottom = document.createElement("div")
    this.rightBottom = document.createElement("div")
    this.leftTop.className = "horn leftTop"
    this.rightTop.className = "horn rightTop"
    this.leftBottom.className = "horn leftBottom"
    this.rightBottom.className = "horn rightBottom"
    this.target.append(this.leftTop)
    this.target.append(this.rightTop)
    this.target.append(this.leftBottom)
    this.target.append(this.rightBottom)
  }
  // 添加四条边
  addBorder() {
    this.left = document.createElement("div")
    this.right = document.createElement("div")
    this._top = document.createElement("div")
    this.bottom = document.createElement("div")
    this.left.className = "vertical left"
    this.right.className = "vertical right"
    this._top.className = "horizontal top"
    this.bottom.className = "horizontal bottom"
    this.target.append(this.left)
    this.target.append(this.right)
    this.target.append(this._top)
    this.target.append(this.bottom)
  }
  // 缩放实现
  zoom(el, direction) {
    el.addEventListener("mousedown", (e) => {
      e.stopPropagation()
      this.getInfo(e)
      document.onmousemove = (e) => {
        switch (direction) {
          case "left": this.leftInfo(e); break;
          case "right": this.rightInfo(e); break;
          case "top": this.topInfo(e); break;
          case "bottom": this.bottomInfo(e); break;
          case "leftTop": this.leftTopInfo(e); break;
          case "leftBottom": this.leftBottomInfo(e); break;
          case "rightTop": this.rightTopInfo(e); break;
          case "rightBottom": this.rightBottomInfo(e); break;
        }
        // 这里不能直接使用对this.newWidth隐式类型转换来判断，因为this.newWidth===0时，会使用this.width
        let width = this.newWidth !== undefined ? this.newWidth : this.width
        let height = this.newHeight !== undefined ? this.newHeight : this.height
        let translateX = this.distanceX !== undefined ? this.distanceX : this.tx
        let translateY = this.distanceY !== undefined ? this.distanceY : this.ty
        this.target.style.width = `${width}px`
        this.target.style.height = `${height}px`
        this.target.style.transform = `translate(${translateX}px, ${translateY}px)`
      }
      document.onmouseup = () => {
        document.onmousemove = null
      }
    })
  }
  // 获取缩放时宽高、translate等参数的值
  leftInfo(e) {
    this.newWidth = this.width - (e.clientX - this.startX)
    this.distanceX = this.tx + (e.clientX - this.startX)
    if (this.options.limit) {
      this.newWidth = Math.max(this.options.minWidth, Math.min(this.newWidth, this.width + this.tx))
      this.distanceX = Math.max(0, Math.min(this.distanceX, this.width + this.tx - this.options.minWidth))
    }
  }
  rightInfo(e) {
    this.newWidth = this.width + (e.clientX - this.startX)
    if (this.options.limit) {
      this.newWidth = Math.max(this.options.minWidth, Math.min(this.newWidth, this.maxWidth - this.tx))
    }
  }
  topInfo(e) {
    this.newHeight = this.height - (e.clientY - this.startY)
    this.distanceY = this.ty + (e.clientY - this.startY)
    if (this.options.limit) {
      this.newHeight = Math.max(this.options.minHeight, Math.min(this.newHeight, this.height + this.ty))
      this.distanceY = Math.max(0, Math.min(this.distanceY, this.height + this.ty - this.options.minHeight))
    }
  }
  bottomInfo(e) {
    this.newHeight = this.height + (e.clientY - this.startY)
    if (this.options.limit) {
      this.newHeight = Math.max(this.options.minHeight, Math.min(this.newHeight, this.maxHeight - this.ty))
    }
  }
  leftTopInfo(e) {
    this.leftInfo(e)
    this.topInfo(e)
  }
  leftBottomInfo(e) {
    this.leftInfo(e)
    this.bottomInfo(e)
  }
  rightTopInfo(e) {
    this.rightInfo(e)
    this.topInfo(e)
  }
  rightBottomInfo(e) {
    this.rightInfo(e)
    this.bottomInfo(e)
  }
  leftZoom() {
    this.zoom(this.left, "left")
  }
  rightZoom() {
    this.zoom(this.right, "right")
  }
  topZoom() {
    this.zoom(this._top, "top")
  }
  bottomZoom() {
    this.zoom(this.bottom, "bottom")
  }
  leftTopZoom() {
    this.zoom(this.leftTop, "leftTop")
  }
  leftBottomZoom() {
    this.zoom(this.leftBottom, "leftBottom")
  }
  rightTopZoom() {
    this.zoom(this.rightTop, "rightTop")
  }
  rightBottomZoom() {
    this.zoom(this.rightBottom, "rightBottom")
  }
}
let t = new Drag(dragEl)
console.log(t)